package petrochina.company.electric.ui.dialog;

import android.content.Context;
import android.content.res.Resources;
import android.os.Handler;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.appcompat.widget.AppCompatButton;
import androidx.appcompat.widget.AppCompatImageView;
import androidx.appcompat.widget.AppCompatTextView;
import androidx.constraintlayout.widget.ConstraintLayout;

import com.hjq.base.BaseDialog;
import com.hjq.toast.ToastUtils;
import com.hjq.widget.view.DrawableTextView;
import com.ut.ble.BleConnectCallback;
import com.ut.ble.BleDevice;
import com.ut.blelock.BleLockController;
import com.ut.blelock.OperateCallback;
import com.ut.blelock.frame.LockInfoResultFrame;
import com.ut.blelock.frame.OperateResultFrame;
import com.ut.blelock.frame.VerifyKeyAck;

import java.util.List;

import petrochina.company.electric.R;
import petrochina.company.electric.aop.SingleClick;
import petrochina.company.electric.http.api.BleDeviceListApi;
import petrochina.company.electric.http.api.TaskDetailStepApi;
import petrochina.company.electric.model.TaskPowerResult;

/**
 * 优特蓝牙锁连接 操作
 */
public final class BleLockOptionMenuDialog {

    public static final class Builder
            extends BaseDialog.Builder<Builder>
            implements
            View.OnLayoutChangeListener, Runnable {

        private boolean isReConnect = false;

        @SuppressWarnings("rawtypes")
        @Nullable
        private OnListener mListener;
        private boolean mAutoDismiss = true;
        BleConnectCallback connectCallback = new BleConnectCallback(BleLockController.getInstance()) {

            @Override
            public void onConnectSuccess(BleDevice bleDevice) {
                super.onConnectSuccess(bleDevice);
                System.out.println("---------onConnectSuccess " + bleDevice.toString() + ", in " + Thread.currentThread());
                getActivity().runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        ToastUtils.show("已连接");
                        // 验证秘钥
//                        if (mTaskPowerResult != null) {
//                            if (mTaskPowerResult.getOperType() == 6) {
//                                verifyLockKey(2);
//                            } else {
//                                verifyLockKey(1);
//                            }

//                        }
                        // 不管最终要求状态，都先打开锁具

                        if (!isReConnect){
                            verifyLockKey(2);
                        }else {
                            verifyLockKey(0);
                        }
                        isReConnect= false;
                        resetconnectStatus(true);
//                        mst.setText("已连接");
                    }
                });
            }

            @Override
            public void onDisconnect(BleDevice bleDevice, boolean isActive) {
                super.onDisconnect(bleDevice, isActive);
                System.out.println("--------- onDisconnect " + isActive + ", in " + Thread.currentThread());
                getActivity().runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
//                        ToastUtils.show("未连接");
                        isReConnect = true;
                        resetconnectStatus(false);
//                        Toast.makeText(BleLockOptActivity.this, "disconnected", Toast.LENGTH_SHORT).show();
//                        statusView.setText("未连接");
//                        statusView.setTextColor(getResources().getColor(android.R.color.darker_gray));
                    }
                });
            }

            @Override
            public void onConnect(BleDevice bleDevice) {
                super.onConnect(bleDevice);
                System.out.println("--------- onConnect " + ", in " + Thread.currentThread());
            }

            @Override
            public void onFailure(final BleDevice bleDevice, final int code, final String message) {
                super.onFailure(bleDevice, code, message);
                System.out.println("--------- onFailure " + bleDevice.toString() + " , " + code + " , " + message + ", in " + Thread.currentThread());
                getActivity().runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
//                        ToastUtils.show("未连接");
                        // 因蓝牙锁激活时间较短完成步骤目标后断开连接不更新UI
                        if (targetStatus != currentStatus){
                            resetconnectStatus(false);
                        }
//                        Toast.makeText(BleLockOptActivity.this, bleDevice.toString() + " , " +
//                                code + " , " + message, Toast.LENGTH_SHORT).show();
//                        statusView.setText("未连接");
//                        statusView.setTextColor(getResources().getColor(android.R.color.darker_gray));
                    }
                });
            }
        };

        /**
         * 验证秘钥
         */
        private void verifyLockKey(int type) {
            BleLockController.getInstance().setVerifyKeyOperateCallback((i, s, verifyKeyAck) -> {
                if (verifyKeyAck.result()) {
                    ToastUtils.show("验证秘钥成功");
                    switch (type) {
                        case 0:
                            getLockInfo();
                            break;
                        case 1:
                            lock();
                            break;
                        case 2:
                            unlock();
                            break;
                    }
//                    getLockInfo();
                } else {
                    ToastUtils.show("验证秘钥失败");
                }
            });
        }

        /**
         * 根据蓝牙锁连接状态调整UI
         *
         * @param connectStatus
         */
        private void resetconnectStatus(boolean connectStatus) {
            mIvBleLockOptStatus.setImageResource(connectStatus ? R.drawable.ble_connected_ic : R.drawable.ble_disconnected_ic);
            mconnectStatusView.setVisibility(connectStatus ? View.VISIBLE : View.GONE);
            mTvBleLockOptStatus.setText(connectStatus ? "蓝牙连接成功" : "蓝牙断开连接");
            mDtStatusNum.setVisibility(connectStatus ? View.VISIBLE : View.GONE);
            mClConnect.setVisibility(connectStatus ? View.VISIBLE : View.GONE);
            mBtnBleOptReconnect.setVisibility(connectStatus ? View.GONE : View.VISIBLE);
//            if (!connectStatus) {
//                mBtnBleOptCancel.setVisibility(View.GONE);
//                mBtnBleOptReload.setVisibility(View.GONE);
//                mBleOptStatusButton.setVisibility(View.GONE);
//                mBtnBleOptReconnect.setVisibility(View.VISIBLE);
//            }

        }

        private final LinearLayout mconnectStatusView;
        private final ConstraintLayout mClConnect;
        private final AppCompatButton mBleOptStatusButton, mBtnBleOptCancel, mBtnBleOptReload, mBtnBleOptReconnect;
        private final AppCompatImageView mIvBleLockOptStatus;
        private final TextView mTvBleLockOptStatus, mTvBleDeviceStatusCurrent, mTvBleDeviceStatus;
        private final AppCompatTextView mTvLockIdCard;
        private final DrawableTextView mDtStatusNum;
        // true : 开锁 false： 关锁
        private Boolean targetStatus;
        private Boolean currentStatus;

        private BleDeviceListApi.Bean mBleDevice;
        private TaskDetailStepApi.Bean mTaskPowerResult;


        public Builder(Context context) {
            super(context);
            initData();
            setContentView(R.layout.ble_lock_option_dialog);
            setAnimStyle(BaseDialog.ANIM_BOTTOM);
            mconnectStatusView = findViewById(R.id.ll_lock_status);
            mClConnect = findViewById(R.id.cl_connect);
            mBleOptStatusButton = findViewById(R.id.btn_ble_opt_status);
            mIvBleLockOptStatus = findViewById(R.id.iv_ble_lock_opt_status);
            mTvLockIdCard = findViewById(R.id.tv_lock_id_card);
            mTvBleLockOptStatus = findViewById(R.id.tv_ble_lock_opt_status);
            mTvBleDeviceStatusCurrent = findViewById(R.id.tv_ble_device_status_current);
            mTvBleDeviceStatus = findViewById(R.id.tv_ble_device_status);
            mDtStatusNum = findViewById(R.id.dt_status_num);
            mBtnBleOptCancel = findViewById(R.id.btn_ble_opt_cancel);
            mBtnBleOptReload = findViewById(R.id.btn_ble_opt_reload);
            mBtnBleOptReconnect = findViewById(R.id.btn_ble_opt_reconnect);
            setOnClickListener(mconnectStatusView, mBleOptStatusButton, mBtnBleOptCancel, mBtnBleOptReload, mBtnBleOptReconnect);

        }

        @Override
        public void show() {
            super.show();
            if (mBleDevice != null) {
                mTvLockIdCard.setText("编号：" + mBleDevice.getCode());
                BleLockController.getInstance().connect(mBleDevice.getDevice(), connectCallback);
                if (mTaskPowerResult != null) {
                    targetStatus = mTaskPowerResult.getOperType() == 6;
                    mTvBleDeviceStatus.setText("预期状态：" + (targetStatus ? "开" : "关"));
                }
            } else {
                dismiss();
            }
        }

        private void initData() {

            //监听蓝牙锁闭锁操作
            BleLockController.getInstance().setLockCallback((code, message, operateResultFrame) -> {
                // 接受到蓝牙锁的操作状态
                getActivity().runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        ToastUtils.show("operate type is " + operateResultFrame.getOperateType() + ", lockSeq is " + operateResultFrame.getLockSequence() + ", result is " + operateResultFrame.getOperateResult());
                    }
                });
            });
        }

        /**
         * 开锁
         */
        public void unlock() {
            BleLockController.getInstance().unlock((code, message, operateResultFrame) -> {
                if (code == OperateCallback.RESPONSE_OK) {
                    // 开锁成功
                    ToastUtils.show("operate type is " + operateResultFrame.getOperateType() + ", lockSeq is " + operateResultFrame.getLockSequence() + ", result is " + operateResultFrame.getOperateResult());
//                    verifyLockKey(0);
//                    currentStatus = false;
                    Handler handler = new Handler();
                    handler.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            // 执行的操作
                            getLockInfo();
                        }
                    }, 200);//5秒后执行Runnable中的run方法

                } else {
                    // 开锁失败
                    ToastUtils.show("unlock failed " + message);
                }
            });
        }

        /**
         * 获取锁信息
         */
        public void getLockInfo() {
            BleLockController.getInstance().getLockInfo((code, message, lockInfoResultFrame) -> {
                if (code == OperateCallback.RESPONSE_OK) {
                    ToastUtils.show("获取锁具信息成功");
                    if (lockInfoResultFrame.bytes.length== 41){
                        byte lock = lockInfoResultFrame.bytes[lockInfoResultFrame.bytes.length - 3];
                        String hexString = String.format("%02X", lock);
                        currentStatus = !"00".equals(hexString);
                        mTvBleDeviceStatusCurrent.setText("实际状态：" + (currentStatus ? "开" : "关"));
                        resetLockStatus();
                    }else {
                        ToastUtils.show("锁具信息读取错误！");
                    }
                } else {
                    // 获取锁具信息失败
                    ToastUtils.show("获取锁具信息失败");
                }
            });
        }

        /**
         * 更新当前锁状态UI
         */
        private void resetLockStatus() {
            if (targetStatus != null && currentStatus != null) {
                if (targetStatus == currentStatus) {
                    if (currentStatus) {
                        // 达到预期-解锁
                        mDtStatusNum.setText("解锁成功");
                        mDtStatusNum.setLeftDrawable(R.drawable.lock_off_success);
                    } else {
                        mDtStatusNum.setText("闭锁成功");
                        mDtStatusNum.setLeftDrawable(R.drawable.lock_off_success);
                    }
                    mDtStatusNum.setTextColor(getResources().getColor(R.color.green));
                    mTvBleDeviceStatusCurrent.setTextColor(getResources().getColor(R.color.common_confirm_text_color));
                    mBleOptStatusButton.setVisibility(View.VISIBLE);
                    mBtnBleOptCancel.setVisibility(View.GONE);
                    mBtnBleOptReload.setVisibility(View.GONE);
                } else {
                    // 比对失败上报统计
                    if (mListener == null) {
                        return;
                    }
                    mListener.onSelected(getDialog(), 1, 0);
                    if (currentStatus) {
                        // 未达到预期-解锁
                        mDtStatusNum.setText("闭锁失败");
                        mDtStatusNum.setLeftDrawable(R.drawable.lock_off_success);
                    } else {
                        mDtStatusNum.setText("解锁失败");
                        mDtStatusNum.setLeftDrawable(R.drawable.lock_off_success);
                    }
                    mDtStatusNum.setTextColor(getResources().getColor(R.color.red));
                    mTvBleDeviceStatusCurrent.setTextColor(getResources().getColor(R.color.red));
                    mBleOptStatusButton.setVisibility(View.GONE);
                    mBtnBleOptCancel.setVisibility(View.VISIBLE);
                    mBtnBleOptReload.setVisibility(View.VISIBLE);
                }
                mBtnBleOptReconnect.setVisibility(View.GONE);

            }
        }

        /**
         * 闭锁
         */
        public void lock() {
            BleLockController.getInstance().lock((code, message, operateResultFrame) -> {
                if (code == OperateCallback.RESPONSE_OK) {
                    ToastUtils.show("operate type is " + operateResultFrame.getOperateType() + ", lockSeq is " + operateResultFrame.getLockSequence() + ", result is " + operateResultFrame.getOperateResult());
                    verifyLockKey(0);
                } else {
                    ToastUtils.show("lock failed " + message);
                }
            });
        }

        @Override
        public Builder setGravity(int gravity) {
            switch (gravity) {
                // 如果这个是在中间显示的
                case Gravity.CENTER:
                case Gravity.CENTER_VERTICAL:
                    // 不显示取消按钮
                    setCancel(null);
                    // 重新设置动画
                    setAnimStyle(BaseDialog.ANIM_SCALE);
                    break;
                default:
                    break;
            }
            return super.setGravity(gravity);
        }

        @Override
        public Builder addOnDismissListener(@NonNull BaseDialog.OnDismissListener listener) {
            return super.addOnDismissListener(listener);
        }

        /**
         * 销毁,释放资源
         */
        @Override
        public void dismiss() {
            BleLockController.getInstance().uninit();
            super.dismiss();
        }

        public Builder setBleDevice(BleDeviceListApi.Bean bleDevice) {
            this.mBleDevice = bleDevice;
            return this;

        }

        public Builder setData(TaskDetailStepApi.Bean taskPowerResult) {
            this.mTaskPowerResult = taskPowerResult;
            return this;
        }

        public Builder setCancel(@StringRes int id) {
            return setCancel(getString(id));
        }

        public Builder setCancel(CharSequence text) {
//            mBleOptStatusButton.setText(text);
            return this;
        }

        public Builder setAutoDismiss(boolean dismiss) {
            mAutoDismiss = dismiss;
            return this;
        }

        @SuppressWarnings("rawtypes")
        public Builder setListener(OnListener listener) {
            mListener = listener;
            return this;
        }

        @SingleClick
        @Override
        public void onClick(View view) {
            if (mAutoDismiss) {
                dismiss();
            }

            if (view == mBleOptStatusButton) {
                if (mListener == null) {
                    return;
                }
                mListener.onSelected(getDialog(), 0, 0);
            } else if (view == mBtnBleOptReconnect) {
                BleLockController.getInstance().connect(mBleDevice.getDevice(), connectCallback);
            } else if (view == mBtnBleOptCancel) {
                if (mListener == null) {
                    return;
                }
                mListener.onCancel(getDialog());
            } else if (view == mBtnBleOptReload) {
                // 重新读值
                verifyLockKey(0);
            }
        }

        /**
         * {@link View.OnLayoutChangeListener}
         */
        @Override
        public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
            // 这里一定要加延迟，如果不加在 Android 9.0 上面会导致 setLayoutParams 无效
            post(this);
        }

        @Override
        public void run() {

        }

        /**
         * 获取屏幕的高度
         */
        private int getScreenHeight() {
            Resources resources = getResources();
            DisplayMetrics outMetrics = resources.getDisplayMetrics();
            return outMetrics.heightPixels;
        }
    }

    public interface OnListener<T> {

        /**
         * 选择条目时回调
         */
        void onSelected(BaseDialog dialog, int position, T t);

        /**
         * 点击取消时回调
         */
        default void onCancel(BaseDialog dialog) {
        }
    }
}